<!DOCTYPE html>
<html style="display: none;" lang="zh">
    <head>
    <meta charset="utf-8">
    <!--
        © Material Theme
        https://github.com/viosey/hexo-theme-material
        Version: 1.5.2 -->
    <script>
        window.materialVersion = "1.5.2"
        // Delete localstorage with these tags
        window.oldVersion = [
            'codestartv1',
            '1.3.4',
            '1.4.0',
            '1.4.0b1',
            '1.5.0'
        ]
    </script>

    <!-- dns prefetch -->
    <meta http-equiv="x-dns-prefetch-control" content="on">

    <link rel="dns-prefetch" href="https://cdn.jsdelivr.net/gh/viosey/hexo-theme-material/source"/>


    <link rel="dns-prefetch" href="https://cdn1.lncld.net"/>










    <link rel="dns-prefetch" href="https://cdn.con.sh"/>




    <!-- Meta & Info -->
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
    <meta name="renderer" content="webkit">
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">

    <!-- Title -->
    
    <title>
        
            搭建 Mastodon 实例 | How to install a Mastodon instance | 
        
        独立世界
    </title>

    <!-- Favicons -->
    <link rel="icon shortcut" type="image/ico" href="/img/favicon.png">
    <link rel="icon" href="/img/favicon.png">

    <meta name="format-detection" content="telephone=no"/>
    <meta name="description" itemprop="description" content="The independent world of YJK">
    <meta name="keywords" content=",VPS,Mastodon">
    <meta name="theme-color" content="#0097A7">

    <!-- Disable Fucking Bloody Baidu Tranformation -->
    <meta http-equiv="Cache-Control" content="no-transform" />
    <meta http-equiv="Cache-Control" content="no-siteapp" />

    <!--[if lte IE 9]>
        <link rel="stylesheet" href="/css/ie-blocker.css">

        
            <script src="/js/ie-blocker.zhCN.js"></script>
        
    <![endif]-->

    <!-- Import lsloader -->
    <script>(function(){window.lsloader={jsRunSequence:[],jsnamemap:{},cssnamemap:{}};lsloader.removeLS=function(a){try{localStorage.removeItem(a)}catch(b){}};lsloader.setLS=function(a,c){try{localStorage.setItem(a,c)}catch(b){}};lsloader.getLS=function(a){var c="";try{c=localStorage.getItem(a)}catch(b){c=""}return c};versionString="/*"+(window.materialVersion||"unknownVersion")+"*/";lsloader.clean=function(){try{var b=[];for(var a=0;a<localStorage.length;a++){b.push(localStorage.key(a))}b.forEach(function(e){var f=lsloader.getLS(e);if(window.oldVersion){var d=window.oldVersion.reduce(function(g,h){return g||f.indexOf("/*"+h+"*/")!==-1},false);if(d){lsloader.removeLS(e)}}})}catch(c){}};lsloader.clean();lsloader.load=function(f,a,b,d){if(typeof b==="boolean"){d=b;b=undefined}d=d||false;b=b||function(){};var e;e=this.getLS(f);if(e&&e.indexOf(versionString)===-1){this.removeLS(f);this.requestResource(f,a,b,d);return}if(e){var c=e.split(versionString)[0];if(c!=a){console.log("reload:"+a);this.removeLS(f);this.requestResource(f,a,b,d);return}e=e.split(versionString)[1];if(d){this.jsRunSequence.push({name:f,code:e});this.runjs(a,f,e)}else{document.getElementById(f).appendChild(document.createTextNode(e));b()}}else{this.requestResource(f,a,b,d)}};lsloader.requestResource=function(b,e,a,c){var d=this;if(c){this.iojs(e,b,function(h,f,g){d.setLS(f,h+versionString+g);d.runjs(h,f,g)})}else{this.iocss(e,b,function(f){document.getElementById(b).appendChild(document.createTextNode(f));d.setLS(b,e+versionString+f)},a)}};lsloader.iojs=function(d,b,g){var a=this;a.jsRunSequence.push({name:b,code:""});try{var f=new XMLHttpRequest();f.open("get",d,true);f.onreadystatechange=function(){if(f.readyState==4){if((f.status>=200&&f.status<300)||f.status==304){if(f.response!=""){g(d,b,f.response);return}}a.jsfallback(d,b)}};f.send(null)}catch(c){a.jsfallback(d,b)}};lsloader.iocss=function(f,c,h,a){var b=this;try{var g=new XMLHttpRequest();g.open("get",f,true);g.onreadystatechange=function(){if(g.readyState==4){if((g.status>=200&&g.status<300)||g.status==304){if(g.response!=""){h(g.response);a();return}}b.cssfallback(f,c,a)}};g.send(null)}catch(d){b.cssfallback(f,c,a)}};lsloader.iofonts=function(f,c,h,a){var b=this;try{var g=new XMLHttpRequest();g.open("get",f,true);g.onreadystatechange=function(){if(g.readyState==4){if((g.status>=200&&g.status<300)||g.status==304){if(g.response!=""){h(g.response);a();return}}b.cssfallback(f,c,a)}};g.send(null)}catch(d){b.cssfallback(f,c,a)}};lsloader.runjs=function(f,c,e){if(!!c&&!!e){for(var b in this.jsRunSequence){if(this.jsRunSequence[b].name==c){this.jsRunSequence[b].code=e}}}if(!!this.jsRunSequence[0]&&!!this.jsRunSequence[0].code&&this.jsRunSequence[0].status!="failed"){var a=document.createElement("script");a.appendChild(document.createTextNode(this.jsRunSequence[0].code));a.type="text/javascript";document.getElementsByTagName("head")[0].appendChild(a);this.jsRunSequence.shift();if(this.jsRunSequence.length>0){this.runjs()}}else{if(!!this.jsRunSequence[0]&&this.jsRunSequence[0].status=="failed"){var d=this;var a=document.createElement("script");a.src=this.jsRunSequence[0].path;a.type="text/javascript";this.jsRunSequence[0].status="loading";a.onload=function(){d.jsRunSequence.shift();if(d.jsRunSequence.length>0){d.runjs()}};document.body.appendChild(a)}}};lsloader.tagLoad=function(b,a){this.jsRunSequence.push({name:a,code:"",path:b,status:"failed"});this.runjs()};lsloader.jsfallback=function(c,b){if(!!this.jsnamemap[b]){return}else{this.jsnamemap[b]=b}for(var a in this.jsRunSequence){if(this.jsRunSequence[a].name==b){this.jsRunSequence[a].code="";this.jsRunSequence[a].status="failed";this.jsRunSequence[a].path=c}}this.runjs()};lsloader.cssfallback=function(e,c,b){if(!!this.cssnamemap[c]){return}else{this.cssnamemap[c]=1}var d=document.createElement("link");d.type="text/css";d.href=e;d.rel="stylesheet";d.onload=d.onerror=b;var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(d,a)};lsloader.runInlineScript=function(c,b){var a=document.getElementById(b).innerText;this.jsRunSequence.push({name:c,code:a});this.runjs()}})();</script>

    <!-- Import queue -->
    <script>function Queue(){this.dataStore=[];this.offer=b;this.poll=d;this.execNext=a;this.debug=false;this.startDebug=c;function b(e){if(this.debug){console.log("Offered a Queued Function.")}if(typeof e==="function"){this.dataStore.push(e)}else{console.log("You must offer a function.")}}function d(){if(this.debug){console.log("Polled a Queued Function.")}return this.dataStore.shift()}function a(){var e=this.poll();if(e!==undefined){if(this.debug){console.log("Run a Queued Function.")}e()}}function c(){this.debug=true}}var queue=new Queue();</script>

    <!-- Import CSS -->
    
        <style id="material_css"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("material_css","https://cdn.jsdelivr.net/gh/viosey/hexo-theme-material/source/css/material.min.css",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>
        <style id="style_css"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("style_css","https://cdn.jsdelivr.net/gh/viosey/hexo-theme-material/source/css/style.min.css",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>

        
            
                <style id="prettify_css"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("prettify_css","https://cdn.jsdelivr.net/gh/viosey/hexo-theme-material/source/css/prettify.min.css",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>
                <style id="prettify_theme"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("prettify_theme","https://cdn.jsdelivr.net/gh/viosey/hexo-theme-material/source/css/prettify/github-v2.min.css",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>
            
        

    

    

    <!-- Config CSS -->

<!-- Other Styles -->
<style>
  body, html {
    font-family: Roboto, "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
    overflow-x: hidden !important;
  }
  
  code {
    font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
  }

  a {
    color: #00838F;
  }

  .mdl-card__media,
  #search-label,
  #search-form-label:after,
  #scheme-Paradox .hot_tags-count,
  #scheme-Paradox .sidebar_archives-count,
  #scheme-Paradox .sidebar-colored .sidebar-header,
  #scheme-Paradox .sidebar-colored .sidebar-badge{
    background-color: #0097A7 !important;
  }

  /* Sidebar User Drop Down Menu Text Color */
  #scheme-Paradox .sidebar-colored .sidebar-nav>.dropdown>.dropdown-menu>li>a:hover,
  #scheme-Paradox .sidebar-colored .sidebar-nav>.dropdown>.dropdown-menu>li>a:focus {
    color: #0097A7 !important;
  }

  #post_entry-right-info,
  .sidebar-colored .sidebar-nav li:hover > a,
  .sidebar-colored .sidebar-nav li:hover > a i,
  .sidebar-colored .sidebar-nav li > a:hover,
  .sidebar-colored .sidebar-nav li > a:hover i,
  .sidebar-colored .sidebar-nav li > a:focus i,
  .sidebar-colored .sidebar-nav > .open > a,
  .sidebar-colored .sidebar-nav > .open > a:hover,
  .sidebar-colored .sidebar-nav > .open > a:focus,
  #ds-reset #ds-ctx .ds-ctx-entry .ds-ctx-head a {
    color: #0097A7 !important;
  }

  .toTop {
    background: #757575 !important;
  }

  .material-layout .material-post>.material-nav,
  .material-layout .material-index>.material-nav,
  .material-nav a {
    color: #757575;
  }

  #scheme-Paradox .MD-burger-layer {
    background-color: #757575;
  }

  #scheme-Paradox #post-toc-trigger-btn {
    color: #757575;
  }

  .post-toc a:hover {
    color: #00838F;
    text-decoration: underline;
  }

</style>


<!-- Theme Background Related-->

    <style>
      body{
        background-color: #F5F5F5;
      }

      /* blog_info bottom background */
      #scheme-Paradox .material-layout .something-else .mdl-card__supporting-text{
        background-color: #fff;
      }
    </style>




<!-- Fade Effect -->

    <style>
      .fade {
        transition: all 800ms linear;
        -webkit-transform: translate3d(0,0,0);
        -moz-transform: translate3d(0,0,0);
        -ms-transform: translate3d(0,0,0);
        -o-transform: translate3d(0,0,0);
        transform: translate3d(0,0,0);
        opacity: 1;
      }

      .fade.out{
        opacity: 0;
      }
    </style>


<!-- Import Font -->
<!-- Import Roboto -->

    <link href="https://cdn.con.sh/css?family=Roboto:300,400,500" rel="stylesheet">


<!-- Import Material Icons -->


    <style id="material_icons"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("material_icons","https://cdn.jsdelivr.net/gh/viosey/hexo-theme-material/source/css/material-icons.css",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>




    <!-- Import jQuery -->
    
        <script>lsloader.load("jq_js","https://cdn.jsdelivr.net/npm/jquery@2.2.1/dist/jquery.min.js", true)</script>
    

    <!-- WebAPP Icons -->
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="application-name" content="独立世界">
    <meta name="msapplication-starturl" content="https://yjk.im/how-to-install-a-mastodon-instance/">
    <meta name="msapplication-navbutton-color" content="#0097A7">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-title" content="独立世界">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <link rel="apple-touch-icon" href="/img/favicon.png">

    <!-- Site Verification -->
    
    

    <!-- RSS -->
    
        
            <link rel=alternate type="application/atom+xml" href="/atom.xml">
        
    

    <!-- The Open Graph protocol -->
    <meta property="og:url" content="https://yjk.im/how-to-install-a-mastodon-instance/">
    <meta property="og:type" content="blog">
    <meta property="og:title" content="搭建 Mastodon 实例 | How to install a Mastodon instance | 独立世界">
    <meta property="og:image" content="/img/favicon.png">
    <meta property="og:description" content="The independent world of YJK">
    <meta property="og:article:tag" content="VPS"> <meta property="og:article:tag" content="Mastodon"> 

    
        <meta property="article:published_time" content="Tue Sep 12 2017 16:01:49 GMT+0800">
        <meta property="article:modified_time" content="Fri Dec 15 2017 16:31:16 GMT+0800">
    

    <!-- The Twitter Card protocol -->
    <meta name="twitter:card" content="summary_large_image">

    <!-- Add canonical link for SEO -->
    
        <link rel="canonical" href="https://yjk.im/how-to-install-a-mastodon-instance/index.html" />
    

    <!-- Structured-data for SEO -->
    
        


<script type="application/ld+json">
{
    "@context": "https://schema.org",
    "@type": "BlogPosting",
    "mainEntityOfPage": "https://yjk.im/how-to-install-a-mastodon-instance/index.html",
    "headline": "搭建 Mastodon 实例 | How to install a Mastodon instance",
    "datePublished": "Tue Sep 12 2017 16:01:49 GMT+0800",
    "dateModified": "Fri Dec 15 2017 16:31:16 GMT+0800",
    "author": {
        "@type": "Person",
        "name": "YJK",
        "image": {
            "@type": "ImageObject",
            "url": "https://v5cdn.b0.upaiyun.com/avatar/5c1963a15ab57f2af68e9ecf6693fbac"
        },
        "description": "Independent World"
    },
    "publisher": {
        "@type": "Organization",
        "name": "独立世界",
        "logo": {
            "@type":"ImageObject",
            "url": "/img/favicon.png"
        }
    },
    "keywords": ",VPS,Mastodon",
    "description": "The independent world of YJK",
}
</script>


    

    <!-- Analytics -->
    
    
    

    <!-- Custom Head -->
    

</head>


    
        <body id="scheme-Paradox" class="lazy">
            <div class="material-layout  mdl-js-layout has-drawer is-upgraded">
                

                <!-- Main Container -->
                <main class="material-layout__content" id="main">

                    <!-- Top Anchor -->
                    <div id="top"></div>

                    
                        <!-- Hamburger Button -->
                        <button class="MD-burger-icon sidebar-toggle">
                            <span class="MD-burger-layer"></span>
                        </button>
                    

                    <!-- Post TOC -->

    
    <!-- Back Button -->
    <!--
    <div class="material-back" id="backhome-div" tabindex="0">
        <a class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon"
           href="#" onclick="window.history.back();return false;"
           target="_self"
           role="button"
           data-upgraded=",MaterialButton,MaterialRipple">
            <i class="material-icons" role="presentation">arrow_back</i>
            <span class="mdl-button__ripple-container">
                <span class="mdl-ripple"></span>
            </span>
        </a>
    </div>
    -->


    <!-- Left aligned menu below button -->
    
    
    <button id="post-toc-trigger-btn"
        class="mdl-button mdl-js-button mdl-button--icon">
        <i class="material-icons">format_list_numbered</i>
    </button>

    <ul class="post-toc-wrap mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect" for="post-toc-trigger-btn" style="max-height:80vh; overflow-y:scroll;">
        <ol class="post-toc"><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#1、手动安装"><span class="post-toc-number">1.</span> <span class="post-toc-text"><a href="#1&#x3001;&#x624B;&#x52A8;&#x5B89;&#x88C5;" class="headerlink" title="1&#x3001;&#x624B;&#x52A8;&#x5B89;&#x88C5;"></a>1&#x3001;&#x624B;&#x52A8;&#x5B89;&#x88C5;</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#搭建-Mastodon"><span class="post-toc-number">1.1.</span> <span class="post-toc-text"><a href="#&#x642D;&#x5EFA;-Mastodon" class="headerlink" title="&#x642D;&#x5EFA; Mastodon"></a>&#x642D;&#x5EFA; Mastodon</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#更新-Mastodon"><span class="post-toc-number">1.2.</span> <span class="post-toc-text"><a href="#&#x66F4;&#x65B0;-Mastodon" class="headerlink" title="&#x66F4;&#x65B0; Mastodon"></a>&#x66F4;&#x65B0; Mastodon</span></a></li></ol></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#2、Docker-方式安装"><span class="post-toc-number">2.</span> <span class="post-toc-text"><a href="#2&#x3001;Docker-&#x65B9;&#x5F0F;&#x5B89;&#x88C5;" class="headerlink" title="2&#x3001;Docker &#x65B9;&#x5F0F;&#x5B89;&#x88C5;"></a>2&#x3001;Docker &#x65B9;&#x5F0F;&#x5B89;&#x88C5;</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#VPS-内存"><span class="post-toc-number">2.1.</span> <span class="post-toc-text"><a href="#VPS-&#x5185;&#x5B58;" class="headerlink" title="VPS &#x5185;&#x5B58;"></a>VPS &#x5185;&#x5B58;</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#安装-Docker、Nginx-及-Docker-Composer"><span class="post-toc-number">2.2.</span> <span class="post-toc-text"><a href="#&#x5B89;&#x88C5;-Docker&#x3001;Nginx-&#x53CA;-Docker-Composer" class="headerlink" title="&#x5B89;&#x88C5; Docker&#x3001;Nginx &#x53CA; Docker Composer"></a>&#x5B89;&#x88C5; Docker&#x3001;Nginx &#x53CA; Docker Composer</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#安装-Mastodon"><span class="post-toc-number">2.3.</span> <span class="post-toc-text"><a href="#&#x5B89;&#x88C5;-Mastodon" class="headerlink" title="&#x5B89;&#x88C5; Mastodon"></a>&#x5B89;&#x88C5; Mastodon</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#配置-Nginx"><span class="post-toc-number">2.4.</span> <span class="post-toc-text"><a href="#&#x914D;&#x7F6E;-Nginx" class="headerlink" title="&#x914D;&#x7F6E; Nginx"></a>&#x914D;&#x7F6E; Nginx</span></a></li></ol></li></ol>
    </ul>
    




<!-- Layouts -->

    <!-- Post Module -->
    <div class="material-post_container">

        <div class="material-post mdl-grid">
            <div class="mdl-card mdl-shadow--4dp mdl-cell mdl-cell--12-col">

                <!-- Post Header(Thumbnail & Title) -->
                
    <!-- Paradox Post Header -->
    
        <!-- Custom Thumbnail -->
        <div class="post_thumbnail-custom mdl-card__media mdl-color-text--grey-50" style="background-image:url(/i/2Ky1rZG.png)">
    
            <p class="article-headline-p">
                搭建 Mastodon 实例 | How to install a Mastodon instance
            </p>
        </div>





                
                    <!-- Paradox Post Info -->
                    <div class="mdl-color-text--grey-700 mdl-card__supporting-text meta">

    <!-- Author Avatar -->
    <div id="author-avatar">
        <img src="https://v5cdn.b0.upaiyun.com/avatar/5c1963a15ab57f2af68e9ecf6693fbac" width="44px" height="44px" alt="Author Avatar"/>
    </div>
    <!-- Author Name & Date -->
    <div>
        <strong>YJK</strong>
        <span>9月 12, 2017</span>
    </div>

    <div class="section-spacer"></div>

    <!-- Favorite -->
    <!--
        <button id="article-functions-like-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon btn-like">
            <i class="material-icons" role="presentation">favorite</i>
            <span class="visuallyhidden">favorites</span>
        </button>
    -->

    <!-- Qrcode -->
    
        <button id="article-functions-qrcode-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon">
    <i class="material-icons" role="presentation">devices other</i>
    <span class="visuallyhidden">devices other</span>
</button>
<ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="article-functions-qrcode-button">
    <li class="mdl-menu__item">在其它设备中阅读本文章</li>
    
        <img src="">
    
</ul>

    

    <!-- Tags (bookmark) -->
    
    <button id="article-functions-viewtags-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon">
        <i class="material-icons" role="presentation">bookmark</i>
        <span class="visuallyhidden">bookmark</span>
    </button>
    <ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="article-functions-viewtags-button">
        <li class="mdl-menu__item">
        <a class="post_tag-link" href="/tags/Mastodon/">Mastodon</a></li><li class="mdl-menu__item"><a class="post_tag-link" href="/tags/VPS/">VPS</a>
    </ul>
    

    <!-- Share -->
    
        <button id="article-fuctions-share-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon">
    <i class="material-icons" role="presentation">share</i>
    <span class="visuallyhidden">share</span>
</button>
<ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="article-fuctions-share-button">
    
    <!-- Leancloud Views -->
        <a class="post_share-link" href="#">
            <li class="mdl-menu__item">
                <span id="/how-to-install-a-mastodon-instance/" class="leancloud-views_num" data-flag-title="搭建 Mastodon 实例 | How to install a Mastodon instance">
     &nbsp;浏览量
</span>

            </li>
        </a>
    

    

    <!-- Share Weibo -->
    

    <!-- Share Twitter -->
    

    <!-- Share Facebook -->
    

    <!-- Share Google+ -->
    

    <!-- Share LinkedIn -->
    

    <!-- Share QQ -->
    

    <!-- Share Telegram -->
    
</ul>

    
</div>

                

                <!-- Post Content -->
                <div id="post-content" class="mdl-color-text--grey-700 mdl-card__supporting-text fade out">
    
        <p>搭建 Mastodon 实例比较耗内存以及宽带，要想好哦 ~</p>
<p>这里有几个推荐的中文 Mastodon 实例</p>
<ul>
<li>Mastodon 中文圈 <a href="https://tootcn.com" target="_blank" rel="noopener">https://tootcn.com</a></li>
<li>ACG.MN <a href="https://acg.mn" target="_blank" rel="noopener">https://acg.mn</a></li>
<li>喵叽 <a href="https://moe.cat" target="_blank" rel="noopener">https://moe.cat</a></li>
<li>长毛象中文站 <a href="https://cmx.im" target="_blank" rel="noopener">https://cmx.im</a></li>
<li>Mastodon <a href="https://mastodon.social" target="_blank" rel="noopener">https://mastodon.social</a></li>
</ul>
<p>2017 年 9 月 12 日更新手动方式安装</p>
<ul>
<li>1、<a href="#1%E3%80%81%E6%89%8B%E5%8A%A8%E5%AE%89%E8%A3%85">手动方式安装</a> 适合有一定基础的童鞋搭建</li>
<li>2、<a href="#2%E3%80%81Docker-%E6%96%B9%E5%BC%8F%E5%AE%89%E8%A3%85">Docker 方式安装</a> 适合小白搭建</li>
</ul>
<h2 id="1、手动安装"><a href="#1、手动安装" class="headerlink" title="1、手动安装"></a>1、手动安装</h2><p>一步一步安装 Mastodon 实例，Ubuntu 16.04 LTS，root 环境。推荐内存大于 2G，若为 KVM 内存小于 2G，<a href="https://yjk.im/vps-swap/">可以设置个 SWAP</a>。</p>
<h3 id="搭建-Mastodon"><a href="#搭建-Mastodon" class="headerlink" title="搭建 Mastodon"></a>搭建 Mastodon</h3><p><strong>更新系统并安装 Nodejs</strong></p>
<pre><code>apt-get update &amp;&amp; apt-get upgrade -y &amp;&amp; apt-get install imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev git curl wget zip vim -y &amp;&amp; curl -sL https://deb.nodesource.com/setup_6.x | bash - &amp;&amp; apt-get install nodejs &amp;&amp; npm install -g yarn
</code></pre><p><strong>安装 PostgresSQL 及 Redis 数据库</strong></p>
<pre><code>apt-get install redis-server redis-tools postgresql postgresql-contrib -y
</code></pre><p>创建数据库用户</p>
<pre><code>su - postgres
psql
CREATE USER mastodon CREATEDB;
\q
exit
</code></pre><p>使用户可以免密码登陆</p>
<pre><code>sed -i &#39;/^local.*postgres.*peer$/a host all     all     127.0.0.1/32    ident&#39; \
/etc/postgresql/9.?/main/pg_hba.conf
</code></pre><p>安装 ident daemon</p>
<pre><code>apt-get install pidentd
systemctl enable pidentd
systemctl start pidentd
systemctl restart postgresql
</code></pre><p><strong>安装 Ruby</strong></p>
<p>安装依赖</p>
<pre><code>apt-get install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev libidn11-dev pkg-config libprotobuf-dev protobuf-compiler -y
</code></pre><p>新建 Mastodon 用户并切换过去</p>
<pre><code>adduser --disabled-password --disabled-login mastodon
su - mastodon
</code></pre><p>安装 rbenv and rbenv-build</p>
<pre><code>git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo &#39;export PATH=&quot;$HOME/.rbenv/bin:$PATH&quot;&#39; &gt;&gt; ~/.bashrc
echo &#39;eval &quot;$(rbenv init -)&quot;&#39; &gt;&gt; ~/.bashrc
source ~/.bashrc
</code></pre><p>退出以生效</p>
<pre><code>exit
</code></pre><p>重新切换回去</p>
<pre><code>su - mastodon
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
</code></pre><p>然后为 Mastodon 用户安装 ruby 2.4.2， <code>install</code> 的时候大概会卡 10 分钟</p>
<pre><code>rbenv install 2.4.2
rbenv global 2.4.2
</code></pre><p>检测是否安装成功</p>
<pre><code>ruby -v
</code></pre><p><strong>开始安装 Mastodon</strong></p>
<pre><code>cd ~
git clone https://github.com/tootsuite/mastodon.git live
cd live
git checkout $(git tag | tail -n 1)
</code></pre><p>安装 bundler </p>
<pre><code>echo &quot;gem: --no-document&quot; &gt; ~/.gemrc
gem install bundler --no-ri
</code></pre><p>开始安装</p>
<pre><code>bundle install --deployment --without development test
yarn install
</code></pre><p>复制配置文件并编辑</p>
<pre><code>cp .env.production.sample .env.production
vim .env.production
</code></pre><p>然后编辑以下内容</p>
<pre><code># 数据库
REDIS_HOST=localhost
REDIS_PORT=6379
DB_HOST=/var/run/postgresql
DB_USER=mastodon
DB_NAME=mastodon_production
DB_PASS=
DB_PORT=5432

# 域名

LOCAL_DOMAIN=yourdomain.com
LOCAL_HTTPS=true

# 发件设置，推荐使用 Mailgun
# E-mail configuration
SMTP_SERVER=mail.yourdomain.com
SMTP_PORT=587
SMTP_LOGIN=noreply@yourdomain.com
SMTP_PASSWORD=YourPassword
SMTP_FROM_ADDRESS=noreply@yourdomain.com

# 保存退出后，执行 3 次 &#39;RAILS_ENV=production bundle exec rake secret&#39; 并将结果分别填入下方
PAPERCLIP_SECRET=
SECRET_KEY_BASE=
OTP_SECRET=

# 保存退出后，执行 1 次 `RAILS_ENV=production bundle exec rake mastodon:webpush:generate_vapid_key` 并将结果填入下方内容
VAPID_PRIVATE_KEY=
VAPID_PUBLIC_KEY=
</code></pre><p>同步数据库</p>
<pre><code>RAILS_ENV=production bundle exec rails db:setup
</code></pre><p>同步静态资源</p>
<pre><code>RAILS_ENV=production bundle exec rails assets:precompile
</code></pre><p>退出 Mastodon 用户</p>
<pre><code>exit
</code></pre><p><strong>将 Mastodon 加入系统服务</strong></p>
<p>Web service</p>
<pre><code>vim /etc/systemd/system/mastodon-web.service
</code></pre><pre><code>[Unit]
 Description=mastodon-web
 After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/live
Environment=&quot;RAILS_ENV=production&quot;
Environment=&quot;PORT=3000&quot;
ExecStart=/home/mastodon/.rbenv/shims/bundle exec puma -C config/puma.rb
TimeoutSec=15
Restart=always

[Install]
WantedBy=multi-user.target
</code></pre><p>Background service </p>
<pre><code>vim /etc/systemd/system/mastodon-sidekiq.service
</code></pre><pre><code>[Unit]
 Description=mastodon-sidekiq
 After=network.target

[Service]
 Type=simple
 User=mastodon
 WorkingDirectory=/home/mastodon/live
 Environment=&quot;RAILS_ENV=production&quot;
 Environment=&quot;DB_POOL=5&quot;
 ExecStart=/home/mastodon/.rbenv/shims/bundle exec sidekiq -c 5 -q default -q mailers -q pull -q push
 TimeoutSec=15
 Restart=always

[Install]
 WantedBy=multi-user.target
</code></pre><p>API service</p>
<pre><code>vim /etc/systemd/system/mastodon-streaming.service
</code></pre><pre><code>[Unit]
 Description=mastodon-streaming
 After=network.target

[Service]
 Type=simple
 User=mastodon
 WorkingDirectory=/home/mastodon/live
 Environment=&quot;NODE_ENV=production&quot;
 Environment=&quot;PORT=4000&quot;
 ExecStart=/usr/bin/npm run start
 TimeoutSec=15
 Restart=always

[Install]
 WantedBy=multi-user.target
</code></pre><p>启用系统服务</p>
<pre><code>systemctl enable /etc/systemd/system/mastodon-*.service
</code></pre><p>运行 Mastodon</p>
<pre><code>systemctl start mastodon-web.service mastodon-sidekiq.service mastodon-streaming.service
</code></pre><p>为 Mastodon 加入定时任务</p>
<pre><code>crontab -u mastodon -e
</code></pre><pre><code>RAILS_ENV=production
@daily cd /home/mastodon/live &amp;&amp; RAILS_ENV=production /home/mastodon/.rbenv/shims/bundle exec rails mastodon:media:remove_remote
</code></pre><p><strong>安装 Nginx 及配置 SSL</strong></p>
<p>安装 acme.sh 以生成 SSL 证书</p>
<pre><code>curl -L get.acme.sh | bash - &amp;&amp; cp /root/.acme.sh/acme.sh /usr/local/bin/ &amp;&amp; chmod +x /usr/local/bin/acme.sh
</code></pre><p><strong>将域名解析到 VPS 所在 IP，能访问了以后</strong>，签发证书</p>
<pre><code>acme.sh --issue --standalone -d example.com
</code></pre><p>生成的</p>
<pre><code>/root/.acme.sh/example.com/fullchain.cer
/root/.acme.sh/example.com/example.com.key
</code></pre><p>是我们需要的，安装 Nginx</p>
<pre><code>wget -O - https://nginx.org/keys/nginx_signing.key | sudo apt-key add - &amp;&amp; echo &quot;deb http://nginx.org/packages/mainline/ubuntu/ $(lsb_release -sc) nginx&quot; &gt; /etc/apt/sources.list.d/nginx.list &amp;&amp; apt-get update &amp;&amp; apt-get install nginx
</code></pre><p>创建配置文件</p>
<pre><code>vim /etc/nginx/conf.d/mastodon.conf
</code></pre><pre><code>map $http_upgrade $connection_upgrade {
  default upgrade;
  &#39;&#39;      close;
}

server {
  listen 80;
  listen [::]:80;
  server_name example.com;
  # Useful for Let&#39;s Encrypt
  location /.well-known/acme-challenge/ { allow all; }
  location / { return 301 https://$host$request_uri; }
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name example.com;

  ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;
  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:10m;

  ssl_certificate /root/.acme.sh/example.com/example.com.cer;
  ssl_certificate_key /root/.acme.sh/example.com/example.com.key;

  keepalive_timeout    70;
  sendfile on;
  client_max_body_size 0;

  root /home/mastodon/live/public;

  gzip on;
  gzip_disable &quot;msie6&quot;;
  gzip_vary on;
  gzip_proxied any;
  gzip_comp_level 6;
  gzip_buffers 16 8k;
  gzip_http_version 1.1;
  gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

  add_header Strict-Transport-Security &quot;max-age=31536000&quot;;

  location / {
    try_files $uri @proxy;
  }

  location ~ ^/(emoji|packs|system/accounts/avatars|system/media_attachments/files) {
    add_header Cache-Control &quot;public, max-age=31536000, immutable&quot;;
    try_files $uri @proxy;
  }

  location @proxy {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header Proxy &quot;&quot;;
    proxy_pass_header Server;

    proxy_pass http://127.0.0.1:3000;
    proxy_buffering off;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;

    tcp_nodelay on;
  }

  location /api/v1/streaming {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header Proxy &quot;&quot;;

    proxy_pass http://127.0.0.1:4000;
    proxy_buffering off;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;

    tcp_nodelay on;
  }

  error_page 500 501 502 503 504 /500.html;
}
</code></pre><p>运行 Nginx</p>
<pre><code>service nginx start
</code></pre><p>然后注册一个账号，设置为管理员：</p>
<pre><code>su - mastodon
cd ~/live
RAILS_ENV=production bundle exec rails mastodon:make_admin USERNAME=your-user-name
</code></pre><h3 id="更新-Mastodon"><a href="#更新-Mastodon" class="headerlink" title="更新 Mastodon"></a>更新 Mastodon</h3><pre><code>su - mastodon
cd ~/live
gem install bundler --no-ri
git fetch
git checkout v1.X.X
bundle install --deployment --without development test
NODE_ENV=production npm upgrade --global yarn
yarn install
RAILS_ENV=production bundle exec rails assets:clean
RAILS_ENV=production bundle exec rails assets:precompile
RAILS_ENV=production bundle exec rails db:migrate
exit
</code></pre><p>然后重启</p>
<pre><code>systemctl restart mastodon-web.service mastodon-sidekiq.service mastodon-streaming.service
</code></pre><h2 id="2、Docker-方式安装"><a href="#2、Docker-方式安装" class="headerlink" title="2、Docker 方式安装"></a>2、Docker 方式安装</h2><blockquote>
<p>以下环境为基于 KVM 虚化的 Debian 8， root 用户</p>
</blockquote>
<h3 id="VPS-内存"><a href="#VPS-内存" class="headerlink" title="VPS 内存"></a>VPS 内存</h3><p>必须为基于 KVM/XEN/HyperV 虚化的 VPS，基于 OpenVZ 虚化的 VPS 不行。推荐内存为 2G 以上，如果内存小于 2G 的话，可以设置个 Swap</p>
<pre><code>dd if=/dev/zero of=/var/swap bs=1024 count=1048576 &amp;&amp; mkswap /var/swap &amp;&amp; swapon /var/swap &amp;&amp; echo &#39;/var/swap   swap   swap   default 0 0&#39; &gt;&gt; /etc/fstab
</code></pre><h3 id="安装-Docker、Nginx-及-Docker-Composer"><a href="#安装-Docker、Nginx-及-Docker-Composer" class="headerlink" title="安装 Docker、Nginx 及 Docker Composer"></a>安装 Docker、Nginx 及 Docker Composer</h3><p>先查看 VPS 内核是否大于 3.10</p>
<pre><code>uname -r
</code></pre><p>一般来说 KVM 虚化下的 Debian 8 内核是 3.16，支持 Docker</p>
<p><strong>安装 Docker CE 及 Nginx</strong></p>
<pre><code>wget http://nginx.org/keys/nginx_signing.key &amp;&amp; apt-key add nginx_signing.key &amp;&amp; rm nginx_signing.key &amp;&amp; echo &quot;deb http://nginx.org/packages/mainline/ubuntu/ xenial nginx&quot; &gt;&gt; /etc/apt/sources.list.d/nginx.list &amp;&amp; echo &quot;deb-src http://nginx.org/packages/mainline/ubuntu/ xenial nginx  &quot; &gt;&gt; /etc/apt/sources.list.d/nginx.list &amp;&amp; echo &quot;deb http://httpredir.debian.org/debian/ jessie-backports main contrib non-free&quot; &gt;&gt; /etc/apt/sources.list.d/backports.list &amp;&amp; echo &quot;deb-src http://httpredir.debian.org/debian/ jessie-backports main contrib non-free&quot; &gt;&gt; /etc/apt/sources.list.d/backports.list &amp;&amp; apt-get update &amp;&amp; apt-get -y install apt-transport-https ca-certificates curl software-properties-common git vim wget &amp;&amp; curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - &amp;&amp; add-apt-repository &quot;deb [arch=amd64] https://download.docker.com/linux/debian  $(lsb_release -cs) stable&quot; &amp;&amp; apt-get update &amp;&amp; apt-get install -t jessie-backports openssl -y &amp;&amp; apt-get -y install docker-ce nginx
</code></pre><p><strong>安装 Docker Compose</strong></p>
<pre><code>curl -L https://github.com/docker/compose/releases/download/1.13.0/docker-compose-`uname -s`-`uname -m` &gt; /usr/local/bin/docker-compose &amp;&amp; chmod +x /usr/local/bin/docker-compose
</code></pre><h3 id="安装-Mastodon"><a href="#安装-Mastodon" class="headerlink" title="安装 Mastodon"></a>安装 Mastodon</h3><p>Clone Mastodon</p>
<pre><code>mkdir /home/mastodon &amp;&amp; git clone https://github.com/tootsuite/mastodon.git /home/mastodon/live &amp;&amp; cd /home/mastodon/live
</code></pre><p>编辑 <code>.env.production</code> 配置文件</p>
<pre><code>cp .env.production.sample .env.production &amp;&amp; vim .env.production
</code></pre><p>按 <code>i</code> 进入编辑模式</p>
<pre><code># 以下两项保持不动
REDIS_HOST=redis
REDIS_PORT=6379

# 以下五项保持不动
DB_HOST=db
DB_USER=postgres
DB_NAME=postgres
DB_PASS=
DB_PORT=5432

# 你的域名
LOCAL_DOMAIN=example.com 
LOCAL_HTTPS=true

# 以下三项稍后设置
PAPERCLIP_SECRET=
SECRET_KEY_BASE=
OTP_SECRET=

# 若只是自己一个人用，去掉下方的井号
# SINGLE_USER_MODE=true

# 邮件设置，去 https://mailgun.com 注册账号并验证域名
SMTP_SERVER=smtp.mailgun.org
SMTP_PORT=587
# SMTP_LOGIN 为 SMTP 登陆用户，例如 postmaster@example.com
SMTP_LOGIN=
# SMTP 密码
SMTP_PASSWORD=
# 发件人
SMTP_FROM_ADDRESS=notifications@example.com

# 默认图片储存在本地，你也可以配置储存到 AWS S3 上
# S3 (optional)
# S3_ENABLED=true
# S3_BUCKET=
# AWS_ACCESS_KEY_ID=
# AWS_SECRET_ACCESS_KEY=
# S3_REGION=
# S3_PROTOCOL=http
# S3_HOSTNAME=192.168.1.123:9000

# 其余保持不动
</code></pre><p>编辑完毕后，按 <code>ESC</code> 退出编辑模式，输入 <code>:wq</code> 保存退出</p>
<p>编译镜像 </p>
<pre><code>docker-compose build
</code></pre><p>生成密钥</p>
<p>以下命令需要运行 3 次，每运行一次后，需要将生成结果最下方一长串字符分别复制到 <code>.env.production</code> 文件稍后设置的那三项<br> <code>PAPERCLIP_SECRET</code> <code>SECRET_KEY_BASE</code> <code>OTP_SECRET</code> 等于号后面，用单引号包裹（<code>PAPERCLIP_SECRET=&#39;XXXXXXXX&#39;</code>）</p>
<pre><code>docker-compose run --rm web rake secret
</code></pre><p>创建数据库</p>
<pre><code>docker-compose run --rm web rake db:migrate
</code></pre><p>同步静态资源</p>
<pre><code>docker-compose run --rm web rake assets:precompile
</code></pre><p>后台运行</p>
<pre><code>docker-compose up -d
</code></pre><h3 id="配置-Nginx"><a href="#配置-Nginx" class="headerlink" title="配置 Nginx"></a>配置 Nginx</h3><p>安装 acme.sh 以生成 SSL 证书</p>
<pre><code>curl -L get.acme.sh | bash - &amp;&amp; cp /root/.acme.sh/acme.sh /usr/local/bin/ &amp;&amp; chmod +x /usr/local/bin/acme.sh
</code></pre><p><strong>将域名解析到 VPS 所在 IP，能访问了以后</strong>，签发证书</p>
<pre><code>service nginx stop &amp;&amp; acme.sh --issue --standalone -d example.com
</code></pre><p>生成的</p>
<pre><code>/root/.acme.sh/example.com/fullchain.cer
/root/.acme.sh/example.com/example.com.key
</code></pre><p>这两个文件是我们需要的</p>
<p>编辑 Nginx 配置文件</p>
<pre><code>vim /etc/nginx/conf.d/live.conf
</code></pre><p>按 <code>i</code> 进入编辑模式，粘贴下方内容进去</p>
<pre><code>map $http_upgrade $connection_upgrade {
  default upgrade;
  &#39;&#39;      close;
}

server {
  listen 80;
  listen [::]:80;
  # 将 example.com 更换为您的域名
  server_name example.com;
  location / { return 301 https://$host$request_uri; }
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  # 将 example.com 更换为您的域名
  server_name example.com;

  ssl_protocols TLSv1.2;
  ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5; 
  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:10m;

  # 将下方证书换成刚才生成的
  ssl_certificate /root/.acme.sh/example.com/fullchain.cer;
  ssl_certificate_key /root/.acme.sh/example.com/example.com.key;

  keepalive_timeout    70;
  sendfile             on;
  client_max_body_size 0;

  root /home/mastodon/live/public;

  gzip on;
  gzip_disable &quot;msie6&quot;;
  gzip_vary on;
  gzip_proxied any;
  gzip_comp_level 6;
  gzip_buffers 16 8k;
  gzip_http_version 1.1;
  gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

  add_header Strict-Transport-Security &quot;max-age=31536000&quot;;

  location / {
    try_files $uri @proxy;
  }

  location ~ ^/(packs|system/media_attachments/files|system/accounts/avatars) {
    add_header Cache-Control &quot;public, max-age=31536000, immutable&quot;;
    try_files $uri @proxy;
  }

  location @proxy {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header Proxy &quot;&quot;;
    proxy_pass_header Server;

    proxy_pass http://127.0.0.1:3000;
    proxy_buffering off;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;

    tcp_nodelay on;
  }

  location /api/v1/streaming {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header Proxy &quot;&quot;;

    proxy_pass http://127.0.0.1:4000;
    proxy_buffering off;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;

    tcp_nodelay on;
  }

  error_page 500 501 502 503 504 /500.html;
}
</code></pre><p>编辑完毕后，按 <code>ESC</code> 退出编辑模式，输入 <code>:wq</code> 保存退出</p>
<p>运行</p>
<pre><code>service nginx start
</code></pre><p>启动 Nginx，访问您的域名，注册一个用户</p>
<p>然后在终端运行</p>
<pre><code># 将 用户名 更换为您注册的用户
docker-compose run --rm web rails mastodon:make_admin USERNAME=用户名
</code></pre><p>大功告成</p>

        
    

    
</div>


                

                <!-- Post Comments -->
                
                    
    <div id="comment" style='padding:10px;' class="vcomment"></div>
<script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
<script src="//cdn.jsdelivr.net/npm/valine/dist/Valine.min.js"></script>
<script>
    var GUEST_INFO = ['nick','mail','link'];
    var guest_info = 'nick,mail,link'.split(',').filter(function(item){
        return GUEST_INFO.indexOf(item) > -1
    });
    var notify = 'true' == true;
    var verify = 'true' == true;
    new Valine({
        el: '.vcomment',
        notify: notify,
        verify: verify,
        appId: "gEUiWMReyWo7xFtsQ3ckMeM3-gzGzoHsz",
        appKey: "K3wQfmOGxRB79vaBSILIGON9",
        placeholder: "ヾﾉ≧∀≦)o来啊，快活啊!",
        pageSize:'10',
        avatar:'identicon',
        lang:'zh-cn'
    });
</script>

                
            </div>

            <!-- Post Prev & Next Nav -->
            <nav class="material-nav mdl-color-text--grey-50 mdl-cell mdl-cell--12-col">
    <!-- Prev Nav -->
    
        <a href="/what-is-mastodon/" id="post_nav-newer" class="prev-content">
            <button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon mdl-color--white mdl-color-text--grey-900" role="presentation">
                <i class="material-icons">arrow_back</i>
            </button>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            新篇
        </a>
    

    <!-- Section Spacer -->
    <div class="section-spacer"></div>

    <!-- Next Nav -->
    
        <a href="/ghost-cli/" id="post_nav-older" class="next-content">
            旧篇
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            <button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon mdl-color--white mdl-color-text--grey-900" role="presentation">
                <i class="material-icons">arrow_forward</i>
            </button>
        </a>
    
</nav>

        </div>
    </div>



                    
                        <!-- Overlay For Active Sidebar -->
<div class="sidebar-overlay"></div>

<!-- Material sidebar -->
<aside id="sidebar" class="sidebar sidebar-colored sidebar-fixed-left" role="navigation">
    <div id="sidebar-main">
        <!-- Sidebar Header -->
        <div class="sidebar-header header-cover" style="background-image: url(https://i.loli.net/2017/12/13/5a30b3e8ceb69.jpg);">
    <!-- Top bar -->
    <div class="top-bar"></div>

    <!-- Sidebar toggle button -->
    <button type="button" class="sidebar-toggle mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon" style="display: initial;" data-upgraded=",MaterialButton,MaterialRipple">
        <i class="material-icons">clear_all</i>
        <span class="mdl-button__ripple-container">
            <span class="mdl-ripple">
            </span>
        </span>
    </button>

    <!-- Sidebar Avatar -->
    <div class="sidebar-image">
        <img src="https://v5cdn.b0.upaiyun.com/avatar/5c1963a15ab57f2af68e9ecf6693fbac" alt="YJK's avatar">
    </div>

    <!-- Sidebar Email -->
    <a data-toggle="dropdown" class="sidebar-brand" href="#settings-dropdown">
        
        <b class="caret"></b>
    </a>
</div>


        <!-- Sidebar Navigation  -->
        <ul class="nav sidebar-nav">
    <!-- User dropdown  -->
    <li class="dropdown">
        <ul id="settings-dropdown" class="dropdown-menu">
            
        </ul>
    </li>

    <!-- Homepage -->
    
        <li id="sidebar-first-li">
            <a href="/">
                
                    <i class="material-icons sidebar-material-icons">home</i>
                
                主页
            </a>
        </li>
        
    

    <!-- Archives  -->
    
        <li class="dropdown">
            <a href="#" class="ripple-effect dropdown-toggle" data-toggle="dropdown">
                
                    <i class="material-icons sidebar-material-icons">inbox</i>
                
                    归档
                <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
            <li>
                <a class="sidebar_archives-link" href="/archives/2017/12/">十二月 2017<span class="sidebar_archives-count">2</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/11/">十一月 2017<span class="sidebar_archives-count">5</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/10/">十月 2017<span class="sidebar_archives-count">2</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/09/">九月 2017<span class="sidebar_archives-count">3</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/08/">八月 2017<span class="sidebar_archives-count">4</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/07/">七月 2017<span class="sidebar_archives-count">1</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/06/">六月 2017<span class="sidebar_archives-count">2</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/05/">五月 2017<span class="sidebar_archives-count">3</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/04/">四月 2017<span class="sidebar_archives-count">1</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/02/">二月 2017<span class="sidebar_archives-count">3</span></a></li><li><a class="sidebar_archives-link" href="/archives/2016/10/">十月 2016<span class="sidebar_archives-count">1</span></a></li><li><a class="sidebar_archives-link" href="/archives/2016/09/">九月 2016<span class="sidebar_archives-count">2</span></a></li><li><a class="sidebar_archives-link" href="/archives/2016/06/">六月 2016<span class="sidebar_archives-count">1</span></a></li><li><a class="sidebar_archives-link" href="/archives/2016/03/">三月 2016<span class="sidebar_archives-count">1</span></a></li><li><a class="sidebar_archives-link" href="/archives/2016/01/">一月 2016<span class="sidebar_archives-count">1</span></a></li><li><a class="sidebar_archives-link" href="/archives/2015/12/">十二月 2015<span class="sidebar_archives-count">6</span></a>
            </ul>
        </li>
        
    

    <!-- Categories  -->
    

    <!-- Pages  -->
    
        <li>
            <a href="/about" title="关于">
                
                    <i class="material-icons sidebar-material-icons">person</i>
                
                关于
            </a>
        </li>
        
    
        <li>
            <a href="/free" title="免费">
                
                    <i class="material-icons sidebar-material-icons">star-circle</i>
                
                免费
            </a>
        </li>
        
    
        <li>
            <a href="/links" title="友链">
                
                    <i class="material-icons sidebar-material-icons">link</i>
                
                友链
            </a>
        </li>
        
    

    <!-- Article Number  -->
    
</ul>


        <!-- Sidebar Footer -->
        <!--
I'm glad you use this theme, the development is no so easy, I hope you can keep the copyright, I will thank you so much.
If you still want to delete the copyrights, could you still retain the first one? Which namely "Theme Material"
It will not impact the appearance and can give developers a lot of support :)

很高兴您使用并喜欢该主题，开发不易 十分谢谢与希望您可以保留一下版权声明。
如果您仍然想删除的话 能否只保留第一项呢？即 "Theme Material"
它不会影响美观并可以给开发者很大的支持和动力。 :)
-->

<!-- Sidebar Divider -->

    <div class="sidebar-divider"></div>


<!-- Theme Material -->

    <a href="https://github.com/viosey/hexo-theme-material"  class="sidebar-footer-text-a" target="_blank">
        <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
            主题 - Material
            <span class="sidebar-badge badge-circle">i</span>
        </div>
    </a>


<!-- Help & Support -->
<!--

-->

<!-- Feedback -->
<!--

-->

<!-- About Theme -->
<!--

-->

    </div>

    <!-- Sidebar Image -->
    

</aside>

                    

                    
                        <!-- Footer Top Button -->
                        <div id="back-to-top" class="toTop-wrap">
    <a href="#top" class="toTop">
        <i class="material-icons footer_top-i">expand_less</i>
    </a>
</div>

                    

                    <!--Footer-->
<footer class="mdl-mini-footer" id="bottom">
    
        <!-- Paradox Footer Left Section -->
        <div class="mdl-mini-footer--left-section sns-list">
    <!-- Twitter -->
    
        <a href="https://twitter.com/tayuo" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn footer-sns-twitter">
                <span class="visuallyhidden">Twitter</span>
            </button><!--
     --></a>
    

    <!-- Facebook -->
    

    <!-- Google + -->
    

    <!-- Weibo -->
    
        <a href="http://weibo.com/tayuo" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn footer-sns-weibo">
                <span class="visuallyhidden">Weibo</span>
            </button><!--
     --></a>
    

    <!-- Instagram -->
    
        <a href="https://instagram.com/tayuo" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn footer-sns-instagram">
                <span class="visuallyhidden">Instagram</span>
            </button><!--
     --></a>
    

    <!-- Tumblr -->
    

    <!-- Github -->
    
        <a href="https://github.com/ygbhf" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn footer-sns-github">
                <span class="visuallyhidden">Github</span>
            </button><!--
     --></a>
    

    <!-- LinkedIn -->
    

    <!-- Zhihu -->
    

    <!-- Bilibili -->
    

    <!-- Telegram -->
    
        <a href="https://t.me/fakeuncle" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn footer-sns-telegram">
                <span class="visuallyhidden">Telegram</span>
            </button><!--
     --></a>
    
    
    <!-- V2EX -->
    
</div>


        <!--Copyright-->
        <div id="copyright">
            Copyright&nbsp;©<script type="text/javascript">var fd = new Date();document.write("&nbsp;" + fd.getFullYear() + "&nbsp;");</script>独立世界
            
        </div>

        <!-- Paradox Footer Right Section -->

        <!--
        I am glad you use this theme, the development is no so easy, I hope you can keep the copyright.
        It will not impact the appearance and can give developers a lot of support :)

        很高兴您使用该主题，开发不易，希望您可以保留一下版权声明。
        它不会影响美观并可以给开发者很大的支持。 :)
        -->

        <div class="mdl-mini-footer--right-section">
            <div>
                <div class="footer-develop-div">Powered by <a href="https://hexo.io" target="_blank" class="footer-develop-a">Hexo</a></div>
                <div class="footer-develop-div">Theme - <a href="https://github.com/viosey/hexo-theme-material" target="_blank" class="footer-develop-a">Material</a></div>
            </div>
        </div>
    
</footer>


                    <!-- Import JS File -->

    <script>lsloader.load("lazyload_js","https://cdn.jsdelivr.net/gh/viosey/hexo-theme-material/source/js/lazyload.min.js", true)</script>



    <script>lsloader.load("js_js","https://cdn.jsdelivr.net/gh/viosey/hexo-theme-material/source/js/js.min.js", true)</script>



    <script>lsloader.load("np_js","https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js", true)</script>


<script type="text/ls-javascript" id="NProgress-script">
    NProgress.configure({
        showSpinner: true
    });
    NProgress.start();
    $('#nprogress .bar').css({
        'background': '#29d'
    });
    $('#nprogress .peg').css({
        'box-shadow': '0 0 10px #29d, 0 0 15px #29d'
    });
    $('#nprogress .spinner-icon').css({
        'border-top-color': '#29d',
        'border-left-color': '#29d'
    });
    setTimeout(function() {
        NProgress.done();
        $('.fade').removeClass('out');
    }, 800);
</script>





    <!-- Leancloud -->
    <script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.1.js"></script>
    <script>
        AV.initialize('gEUiWMReyWo7xFtsQ3ckMeM3-gzGzoHsz', 'K3wQfmOGxRB79vaBSILIGON9');
    </script>
    <script type="text/ls-javascript" id="leancloud-views-script">
    function showTime(Counter) {
        var query = new AV.Query(Counter);
        $('.leancloud-views_num').each(function() {
            var url = $(this).attr('id').trim();
            query.equalTo('url', url);
            query.find({
                success: function(results) {
                    if (results.length === 0) {
                        var content = '0 ' + $(document.getElementById(url)).text();
                        $(document.getElementById(url)).text(content);
                        return;
                    }
                    for (var i = 0; i < results.length; i++) {
                        var object = results[i];
                        var content = object.get('time') + ' ' + $(document.getElementById(url)).text();
                        $(document.getElementById(url)).text(content);
                    }
                },
                error: function(object, error) {
                    console.log('Error: ' + error.code + ' ' + error.message);
                }
            });
        });
    }

    function addCount(Counter) {
      var Counter = AV.Object.extend('Counter');
      url = $('.leancloud-views_num').attr('id').trim();
      title = $('.leancloud-views_num').attr('data-flag-title').trim();
      var query = new AV.Query(Counter);
      query.equalTo('url', url);
      query.find({
          success: function(results) {
            if (results.length > 0) {
                var counter = results[0];
                counter.fetchWhenSave(true);
                counter.increment('time');
                counter.save(null, {
                    success: function(counter) {
                        var content =  counter.get('time') + ' ' + $(document.getElementById(url)).text();
                        $(document.getElementById(url)).text(content);
                    },
                    error: function(counter, error) {
                        console.log('Failed to save Visitor num, with error message: ' + error.message);
                    }
                });
            } else {
              var newcounter = new Counter();
              newcounter.set('title', title);
              newcounter.set('url', url);
              newcounter.set('time', 1);
              newcounter.save(null, {
                  success: function(newcounter) {
                      console.log('newcounter.get(\'time\')='+newcounter.get('time'));
                      var content = newcounter.get('time') + ' ' + $(document.getElementById(url)).text();
                      $(document.getElementById(url)).text(content);
                  },
                  error: function(newcounter, error) {
                      console.log('Failed to create');
                  }
              });
            }
        },
        error: function(error) {
            console.log('Error:' + error.code + ' ' + error.message);
        }
      });
    }
    $(function() {
        var Counter = AV.Object.extend('Counter');
        if ($('.leancloud-views_num').length === 1) {
            addCount(Counter);
        } else if ($('.post-title-link').length > 1) {
            showTime(Counter);
        }
    });
</script>






   





<!-- UC Browser Compatible -->
<script>
	var agent = navigator.userAgent.toLowerCase();
	if(agent.indexOf('ucbrowser')>0) {
		document.write('<link rel="stylesheet" href="/css/uc.css">');
	   alert('由于 UC 浏览器使用极旧的内核，而本网站使用了一些新的特性。\n为了您能更好的浏览，推荐使用 Chrome 或 Firefox 浏览器。');
	}
</script>

<!-- Import prettify js  -->

    
        
            <script>lsloader.load("prettify_js","https://cdn.jsdelivr.net/gh/viosey/hexo-theme-material/source/js/prettify.min.js", true)</script>
        
    



<!-- Window Load -->
<!-- add class for prettify -->
<script type="text/ls-javascript" id="window-load">
    $(window).on('load', function() {
        // Post_Toc parent position fixed
        $('.post-toc-wrap').parent('.mdl-menu__container').css('position', 'fixed');
    });

    
        
            $(function() {
                $('pre').addClass('prettyprint linenums').attr('style', 'overflow:auto;');
                prettyPrint();
                })
        
    
    
</script>

<!-- MathJax Load-->


<!-- Bing Background -->


<script type="text/ls-javascript" id="lazy-load">
    // Offer LazyLoad
    queue.offer(function(){
        $('.lazy').lazyload({
            effect : 'show'
        });
    });

    // Start Queue
    $(document).ready(function(){
        setInterval(function(){
            queue.execNext();
        },200);
    });
</script>

<!-- Custom Footer -->



<script>
    (function(){
        var scriptList = document.querySelectorAll('script[type="text/ls-javascript"]')

        for (var i = 0; i < scriptList.length; ++i) {
            var item = scriptList[i];
            lsloader.runInlineScript(item.id,item.id);
        }
    })()
console.log('\n %c © Material Theme | Version: 1.5.2 | https://github.com/viosey/hexo-theme-material %c \n', 'color:#455a64;background:#e0e0e0;padding:5px 0;border-top-left-radius:5px;border-bottom-left-radius:5px;', 'color:#455a64;background:#e0e0e0;padding:5px 0;border-top-right-radius:5px;border-bottom-right-radius:5px;');
</script>

                </main>
            </div>
        </body>
    
<script>var OriginTitile=document.title;var st;document.addEventListener('visibilitychange',function(){if(document.hidden){document.title="呀，崩溃了 (´O｀)";clearTimeout(st);console.log('hide');}else{document.title='呀，又好了 ｡◕‿◕｡ ';console.log('show');st=setTimeout(function(){document.title=OriginTitile;},3000);console.log('endChange=');}});</script>
<script>var _hmt =_hmt ||[];(function() {var hm =document.createElement("script");hm.src ="https://hm.baidu.com/hm.js?02443f8f3608593eba77294d5c5f0a21";var s =document.getElementsByTagName("script")[0];s.parentNode.insertBefore(hm,s);})();</script>
</html>
